package com.jie.other.jetpack.paging

import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.AbstractSavedStateViewModelFactory
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import com.jie.commonlib.base.BaseActivity
import com.jie.commonlib.widget.ToastHelper
import com.jie.other.R
import com.jie.other.databinding.OtherActivityPagingBinding
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChangedBy

/**
 * Paging框架学习页面
 */
class PagingActivity : BaseActivity() {
    private lateinit var mViewBinding : OtherActivityPagingBinding
    // 构造指定参数的PagingViewModel
    private val mViewModel : PagingViewModel by viewModels {
        object : AbstractSavedStateViewModelFactory(this@PagingActivity, null) {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(
                key: String,
                modelClass: Class<T>,
                handle: SavedStateHandle
            ): T {
                return PagingViewModel(dataFromHttp()) as T
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mViewBinding = OtherActivityPagingBinding.inflate(layoutInflater)
        setContentView(mViewBinding.root)
        initActionBar()
        initView()
    }

    /**
     * 初始化ActionBar
     */
    private fun initActionBar() {
        val dataFromStr = if (dataFromHttp()) "网络" else "数据库"
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.title = "${getString(R.string.other_paging)}-$dataFromStr"
    }

    private fun initView() {
        val pagingAdapter = PagingAdapter().apply {
            mItemClick = {
                ToastHelper.show(it?.fullName)
            }
        }
        mViewBinding.run {
            rvList.adapter = pagingAdapter.withLoadStateFooter(
                LoadMoreAdapter {
                    pagingAdapter.retry()
                }
            )
            refreshView.setOnRefreshListener {
                pagingAdapter.refresh()
            }
        }
        lifecycleScope.launchWhenCreated {
            pagingAdapter.loadStateFlow
                .distinctUntilChangedBy { it.refresh } // 去重
                .collectLatest {
                mViewBinding.emptyView.apply {
                    val isEmpty = pagingAdapter.itemCount == 0
                    if (it.refresh is LoadState.Error) {
                        showOrHiddenFailed(isEmpty)
                        ToastHelper.show((it.refresh as LoadState.Error).error.message)
                    } else if (it.refresh is LoadState.NotLoading) {
                        // 这里要数据加载完成后再显示空数据，不然第一次打开无法显示数据库中数据
                        showOrHiddenEmpty(it.append.endOfPaginationReached && isEmpty)
                    }
                }
                mViewBinding.refreshView.isRefreshing = it.refresh is LoadState.Loading
            }
        }
        lifecycleScope.launchWhenCreated {
            mViewModel.getList().collectLatest {
                pagingAdapter.submitData(it)
            }
        }
    }

    /**
     * 判断数据来源是否为网络数据
     */
    private fun dataFromHttp() = intent?.extras?.getBoolean(PARAM_DATA_SOURCE) ?: false

    companion object{
        // 新增数据来源参数，true:只读取网络数据 false:先读取数据库，若数据库为空，则请求网络数据到数据库
        const val PARAM_DATA_SOURCE = "dataSource"
    }

}